package com.sheep.advanceddemo.service.impl;

import com.sheep.advanceddemo.entity.SysRole;
import com.sheep.advanceddemo.entity.SysUser;
import com.sheep.advanceddemo.mapper.SysUserMapper;
import com.sheep.advanceddemo.service.SysUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class SysUserDetailsServiceImpl implements SysUserDetailsService {
    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //根据用户名去数据库中查询指定用户，这就要保证数据库中的用户的名称必须唯一，否则将会报错
        SysUser sysUser = sysUserMapper.findUserByUsername(username);
        //如果没有查询到这个用户，说明数据库中不存在此用户，认证失败
        if (sysUser == null) {
            throw new UsernameNotFoundException("user not exist");
        }

        //获取该用户所对应的所有角色，当查询用户的时候级联查询其所关联的所有角色，用户与角色是多对多关系
        //如果这个用户没有所对应的角色，也就是一个空集合，那么在登录的时候会报 403 没有权限异常，切记这点
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        List<SysRole> sysRoles = sysUser.getSysRoles();
        for (SysRole sysRole : sysRoles) {
            authorities.add(new SimpleGrantedAuthority(sysRole.getName()));
        }

        //最终需要返回一个SpringSecurity的UserDetails对象，{noop}表示不加密认证
        //org.springframework.security.core.userdetails.User实现了UserDetails对象，是SpringSecurity内置认证对象
        return new User(sysUser.getUsername(), sysUser.getPassword(), authorities);
    }
}
